#pragma once
#include"util.hpp"
#include<mutex>

class user_table
{
public:
    user_table()
    {
        _mysql = mysql_util::mysql_create();
    }

    ~user_table()
    {
        mysql_util::mysql_destory(_mysql);
    }

    //新增用户
    bool insert(const Json::Value& user)
    {
        if(user["username"].isNull() || user["password"].isNull())
        {
            DLOG("username or password is null");
            return false;
        }
        std::string username =  user["username"].asString();
        Json::Value temp;
        if(select_by_name(username,temp))
        {
            DLOG("username repeat");
            return false;
        }
        std::string password = user["password"].asString();
        std::stringstream  ss;
        ss << "insert into user values(null,'" << username << "','" << password << "',1000,0,0);";
        return mysql_util::mysql_exec(_mysql,ss.str());
    }

    bool login(const Json::Value& user)
    {   
        if(user["username"].isNull() || user["password"].isNull())
        {
            DLOG("username or password is null");
            return false;
        }
        std::string username =  user["username"].asString();
        std::string password = user["password"].asString();
        std::stringstream  ss;
        ss << "select username,password from user where username='" << username << "' and password='" << password << "';";
        MYSQL_RES* res = nullptr;
        {
            std::unique_lock<std::mutex> ul(_mutex);
            bool ret = mysql_util::mysql_exec(_mysql,ss.str());
            if(ret == false)
            {
                return false;
            }
            res = mysql_store_result(_mysql);
        }   
        int row  = mysql_num_rows(res);
        mysql_free_result(res);
        if(row == 0)
        {
            DLOG("login fail");
            return false;
        }
        else
        {
            DLOG("login success");
            return true;
        }
    }

    bool select_by_name(const std::string& username,Json::Value& user)
    {
        std::stringstream ss;
        ss << "select * from user where username='" << username << "';";
        MYSQL_RES* res = nullptr;
        {
            std::unique_lock<std::mutex> ul(_mutex);
            bool ret = mysql_util::mysql_exec(_mysql,ss.str());
            if(ret == false)
            {
                return false;
            }
            res = mysql_store_result(_mysql);
        }
        int row_num =  mysql_num_rows(res);
        if(row_num == 0)
        {
            DLOG("not find");
            mysql_free_result(res);
            return false;
        }  
        MYSQL_ROW  row = mysql_fetch_row(res);
        user["id"] = std::stoi(row[0]);
        user["username"] = username;
        user["password"] = row[2];
        user["score"] = std::stoi(row[3]);
        user["total_count"] = std::stoi(row[4]);
        user["win_count"] = std::stoi(row[5]);
        mysql_free_result(res);
        return true;
    }

    bool select_by_id(int id,Json::Value& user)
    {
        std::stringstream ss;
        ss << "select * from user where id=" << id << ";";
        MYSQL_RES*  res = nullptr;
        {
            std::unique_lock<std::mutex> ul(_mutex);
            bool ret = mysql_util::mysql_exec(_mysql,ss.str());
            if(ret == false)
            {
                return false;
            }
            res = mysql_store_result(_mysql);
        }
        int row_num =  mysql_num_rows(res);
        if(row_num == 0)
        {
            DLOG("not find");
            mysql_free_result(res);
            return false;
        }  
        MYSQL_ROW  row = mysql_fetch_row(res);
        user["id"] = id;
        user["username"] = row[1];
        user["password"] = row[2];
        user["score"] = std::stoi(row[3]);
        user["total_count"] = std::stoi(row[4]);
        user["win_count"] = std::stoi(row[5]);
        mysql_free_result(res);
        return true;
    }

    bool win(int id)
    {
        std::stringstream ss;
        ss << "update user set score=score+30,total_count=total_count+1,win_count=win_count+1 where id=" << id << ";";
        return mysql_util::mysql_exec(_mysql,ss.str());
    }

    bool lose(int id)
    {
        std::stringstream ss;
        ss << "update user set score=score-30,total_count=total_count+1 where id=" << id << ";";
        return mysql_util::mysql_exec(_mysql,ss.str());
    }

private:
    std::mutex _mutex;
    MYSQL* _mysql;
};




